package com.yanqu.road.server.manger.activity.yqhotel;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;

import com.yanqu.road.entity.activity.yqhotel.config.*;
import com.yanqu.road.entity.activity.yqhotel.data.YqHotelEventData;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.logic.activity.yqhotel.YQHotelConfig;

import com.yanqu.road.pb.activity.YqHotelProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.yqhotel.YqHotelModule;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;

import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class YqHotelMgr extends TempMgr {

    private static RandomHelper randomHelper = new RandomHelper();

    private static YQHotelConfig config;

    private static Map<String, YqHotelProto.YqHotelConfigDataSyncMsg.Builder> configBuilderMap = new ConcurrentHashMap<>();

    public static void reloadActivityData(){
        getLogger().info("reload YQHotel activity start");
        // 获取活动
        ActivityInfo tmpActivityInfo;
        List<ActivityInfo> openActivityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.YQHotel.getValue());

        if (openActivityInfoList.size() <= 0) {
            getLogger().info("no YQHotel activity in show time");
            config = null;
            //清空配置
            configBuilderMap = new ConcurrentHashMap<>();
            return;
        }
        tmpActivityInfo = openActivityInfoList.get(0);
        // 活动配置
        Map<String, ActivityConfig> activityConfigMap = NormalActivityMgr.getActivityConfigMap(tmpActivityInfo.getActivityId());
        config = new YQHotelConfig(tmpActivityInfo, activityConfigMap);
        //清空配置
        configBuilderMap = new ConcurrentHashMap<>();

        reloadPlayerData();

        getLogger().info("reload YQHotel activity end,activityId{}",config.getActivityId());
    }

    private static void reloadPlayerData() {
        if (ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            for (GamePlayer player : GamePlayerMgr.getCopyPlayerMap().values()) {
                if (SystemOpenMgr.systemOpen(player, eSystemId.YQHotel.getValue())) {
                    player.getModule(YqHotelModule.class).initSystem();

                }
            }
        }

    }


    //获取加速的消耗当前结算对应的魂力的头衔
    public static Property getAccelerateTimeCost(Map<Integer,Long> leftSoulMap, Map<Integer,Long> rightSoulMap, int studyBuildingId){
        long leftSoulValue = 0,rightSoulValue = 0;
        for(int buildingId : leftSoulMap.keySet()){
            if(buildingId < studyBuildingId){
                leftSoulValue += leftSoulMap.get(buildingId);
            }
        }
        for(int buildingId : rightSoulMap.keySet()){
            if(buildingId < studyBuildingId){
                rightSoulValue += leftSoulMap.get(buildingId);
            }
        }
        YqHotelTitleConfig titleConfig = getTitleConfigBySoul(leftSoulValue > rightSoulValue ? leftSoulValue:rightSoulValue);
        if(titleConfig == null){
            getLogger().error("斗罗史莱克学院配置异常，出现了找不到加速消耗的配置");
            return PropertyHelper.parseStringToProperty(config.getYQHOTEL_COST_NUM_ID() + "=" + Integer.MAX_VALUE);
        }
        return PropertyHelper.parseStringToProperty(config.getYQHOTEL_COST_NUM_ID() + "=" + titleConfig.getAccelerateTimeCost());
    }

    //随机一个空的建筑的不存在的随机事件
    public static YqHotelEventData randomBuildingEvent(Map<Integer, YqHotelEventData> userEventMap, long eventTime){
        List<Integer> buildingIdList = new ArrayList<>();
        Map<Integer, YqHotelEventConfig> eventMap = new ConcurrentHashMap<>(config.getEventConfigMap());
        for(YqHotelEventData userEvent : userEventMap.values()){
            if(userEvent.getEventId() == 0){
                buildingIdList.add(userEvent.getBuildingId());
            }
            if(userEvent.getEventId() != 0){
                eventMap.remove(userEvent.getEventId());
            }
        }
        if(buildingIdList.size() > 0){
            int randomBuildingIndex = randomHelper.next(0,buildingIdList.size());
            int randomEventIndex = randomHelper.next(0,eventMap.size());
            int buildingId = buildingIdList.get(randomBuildingIndex);
            int eventId = new ArrayList<>(eventMap.keySet()).get(randomEventIndex);
            userEventMap.get(buildingId).setEventId(eventId);
            userEventMap.get(buildingId).setEventTime(eventTime);
            return userEventMap.get(buildingId);
        }
        return null;
    }

    public static int getBossKillTimes(int bossId){

        YqHotelBeastConfig beastConfig = config.getBeastConfigMap().get(bossId);
        if (beastConfig == null){
            return Integer.MAX_VALUE;
        }
        return beastConfig.getKillTimes();
    }

    public static int getNextBossId(int nowBossId){
        int tempBossId = Integer.MAX_VALUE;
        if(config != null){
            for(YqHotelBeastConfig beastConfig : config.getBeastConfigMap().values()){
                if(beastConfig.getId() > nowBossId && beastConfig.getId() < tempBossId){
                    tempBossId = beastConfig.getId();
                }
            }
        }
        //返回0表示boss死光了
        if(tempBossId == Integer.MAX_VALUE){
            return 0;
        }
        return tempBossId;
    }

    public static BigInteger getBossBlood(int bossId){
        YqHotelBeastConfig yqHotelBeastConfig = config.getBeastConfigMap().get(bossId);
        if (yqHotelBeastConfig == null){
            return BigInteger.ZERO;
        }

        return yqHotelBeastConfig.getBlood();
    }

    public static Property getSolderBeatRewards(long soulValue){
        Property property = new Property();
        for(YqHotelTitleConfig titleConfig : config.getTitleConfigMap().values()){
            if(soulValue >= titleConfig.getSmallValue() && soulValue < titleConfig.getBigValue()){
                return PropertyHelper.parseStringToProperty(titleConfig.getRewards());
            }
        }
        return property;
    }



    public static YqHotelTitleConfig getTitleConfigBySoul(long soulValue){

        for(YqHotelTitleConfig titleConfig : config.getTitleConfigMap().values()){
            if(soulValue >= titleConfig.getSmallValue() && soulValue < titleConfig.getBigValue()){
                return titleConfig;
            }
        }
        return null;
    }

    public static Property getBossRewards(int boosId){
        return PropertyHelper.parseStringToProperty(config.getBeastConfigMap().get(boosId).getRewards());
    }

    public static boolean isEnrolBuildingId(int buildingId){
        if (config == null) {
            return buildingId == 1;
        }
        return buildingId == config.getEnrolBuildingId();
    }

    public static int getShuangTypeRandom(int buildingLevel){
        Map<Integer, YqHotelSkillConfig> skillConfigMap = config.getSkillConfigMap().get(config.getSoulCheckBuildingId());
        YqHotelSkillConfig skillConfig = skillConfigMap.get(buildingLevel);
        int randomValue = randomHelper.next(0,1000);
        if(skillConfig.getWeight() > randomValue){
            return 2;
        }
        return 1;
    }

    public static String getJinHunBiReward(int num){
        return config.getYQHOTEL_COST_NUM_ID() + "=" + num;
    }

    public static YqHotelCounterConfig getBuildingConfig(int buildingId, int level){
        Map<Integer, Map<Integer, YqHotelCounterConfig>> counterConfig = config.getCounterConfigMap();
        if(!counterConfig.containsKey(buildingId)){
            return null;
        }
        Map<Integer, YqHotelCounterConfig> counterConfigMap = counterConfig.get(buildingId);
        if(!counterConfigMap.containsKey(level)){
            return null;
        }
        return counterConfigMap.get(level);
    }

    public static YqHotelSkillConfig getSkillConfig(int buildingId, int level){
        Map<Integer, Map<Integer, YqHotelSkillConfig>> skillConfig = config.getSkillConfigMap();
        if(!skillConfig.containsKey(buildingId)){
            return null;
        }
        Map<Integer, YqHotelSkillConfig> skillConfigMap = skillConfig.get(buildingId);
        if(!skillConfigMap.containsKey(level)){
            return null;
        }
        return skillConfigMap.get(level);
    }

    //每分钟产生多少学生
    public static int getStudentSpeed(int level){
        Map<Integer, Map<Integer, YqHotelSkillConfig>> skillConfigMap = config.getSkillConfigMap();
        YqHotelSkillConfig skillConfig = skillConfigMap.get(config.getEnrolBuildingId()).get(level);
        if(skillConfig == null){
            return 0;
        }
        return StringUtils.parseInt(skillConfig.getSkillEffect());
    }

    public static long randomSoulValue(int buildingId,int buildingLevel){
        if(buildingId == config.getEnrolBuildingId()){
            return 0;
        }
        YqHotelSkillConfig skillConfig = config.getSkillConfigMap().get(buildingId).get(buildingLevel);
        if(skillConfig == null){
            return 0;
        }
        List<Integer> rangeValueList = StringUtils.stringToIntegerList(skillConfig.getSkillEffect(),",");
        return randomHelper.next(rangeValueList.get(0),rangeValueList.get(1));
    }

    //返回对应建筑的等待人数 招待所和魂力检测仪会随着等级翻倍
    public static int getWaitSeat(int buildingId,int buildingSeat){
        List<Integer> seatList = config.getYqHotelQueueNum();
        if(buildingId == config.getEnrolBuildingId() || buildingId == config.getSoulCheckBuildingId()){
            return buildingSeat * seatList.get(buildingId-1);
        }
        return seatList.get(buildingId-1);
    }

    public static int getBuildingSeat(int buildingId,int level){
        return config.getBuildingSeatMap().get(buildingId).get(level);
    }

    /**
     * 是否在清空道具时间内 没用了现在
     */
    public static boolean isActivityInClearTime() {
        if (config == null) {
            return false;
        }
        return ActivityMgr.activityInRewardPeriod(config.getActivityInfo());
    }

    /**
     * 获取展示中的活动ID（0表示没活动）
     */
    public static int getActivityTimeAcId() {
        if (config == null) {
            return 0;
        }

        ActivityInfo activityInfo = config.getActivityInfo();
        if(ActivityMgr.activityInShowTime(activityInfo) ){
            return activityInfo.getActivityId();
        }
        return 0;
    }

    public static YqHotelProto.YqHotelConfigDataSyncMsg.Builder getConfigBuilder(String language){
        if (config == null) {
            return null;
        }
        if (!configBuilderMap.containsKey(language)) {
            synchronized (configBuilderMap) {
                if (!configBuilderMap.containsKey(language)) {
                    YqHotelProto.YqHotelConfigDataSyncMsg.Builder builder = initConfigBuilder(language);
                    if (builder != null) {
                        configBuilderMap.put(language, builder);
                    }
                }
            }
        }
        return configBuilderMap.get(language);
    }

    public static YqHotelProto.YqHotelConfigDataSyncMsg.Builder initConfigBuilder(String language){
        if (config == null) {
            return null;
        }
        YqHotelProto.YqHotelConfigDataSyncMsg.Builder builder = YqHotelProto.YqHotelConfigDataSyncMsg.newBuilder();
        builder.setActivityId(config.getActivityId());

        YqHotelProto.YqHotelConfigDataTemp.Builder configBuild = YqHotelProto.YqHotelConfigDataTemp.newBuilder();

        for(Map<Integer, YqHotelSkillConfig> buildingSkillMap : config.getSkillConfigMap().values()){
            for(YqHotelSkillConfig skillConfig : buildingSkillMap.values()){
                YqHotelProto.YqHotelSkillConfigTemp.Builder skillBuilder = YqHotelProto.YqHotelSkillConfigTemp.newBuilder();
                skillBuilder.setType(skillConfig.getType());
                skillBuilder.setLevel(skillConfig.getLevel());
                skillBuilder.setIcon(skillConfig.getIcon());
                skillBuilder.setName(ServerLanguageMgr.getContent(skillConfig.getName(),language));
                skillBuilder.setDesc(ServerLanguageMgr.getContent(skillConfig.getDesc(),language));
                skillBuilder.setCost(skillConfig.getCost());
                skillBuilder.setSkillEffect(skillConfig.getSkillEffect());
                skillBuilder.setWeight(skillConfig.getWeight());
                configBuild.addSkills(skillBuilder);
            }
        }

        for(Map<Integer, YqHotelCounterConfig> buildingCounterMap : config.getCounterConfigMap().values()){
            for(YqHotelCounterConfig counterConfig : buildingCounterMap.values()){
                YqHotelProto.YqHotelCounterConfigTemp.Builder counterBuilder = YqHotelProto.YqHotelCounterConfigTemp.newBuilder();
                counterBuilder.setType(counterConfig.getType());
                counterBuilder.setLevel(counterConfig.getLevel());
                counterBuilder.setNum(counterConfig.getNum());
                counterBuilder.setConsume(counterConfig.getConsume());
                configBuild.addCounters(counterBuilder);
            }
        }


        for(YqHotelTitleConfig titleConfig : config.getTitleConfigMap().values()){
            YqHotelProto.YqHotelTitleConfigTemp.Builder titleBuilder = YqHotelProto.YqHotelTitleConfigTemp.newBuilder();
            titleBuilder.setId(titleConfig.getId());
            titleBuilder.setIcon(titleConfig.getIcon());
            titleBuilder.setName(ServerLanguageMgr.getContent(titleConfig.getName(),language));
            titleBuilder.setDesc(ServerLanguageMgr.getContent(titleConfig.getDesc(),language));
            titleBuilder.setSourPower(titleConfig.getSourPower());
            titleBuilder.setRewards(titleConfig.getRewards());
            titleBuilder.setAccelerateTimeCost(titleConfig.getAccelerateTimeCost());
            configBuild.addTitles(titleBuilder);
        }

        for(YqHotelBeastConfig beastConfig : config.getBeastConfigMap().values()){
            YqHotelProto.YqHotelBeastConfigTemp.Builder beastBuilder = YqHotelProto.YqHotelBeastConfigTemp.newBuilder();
            beastBuilder.setId(beastConfig.getId());
            beastBuilder.setIcon(beastConfig.getIcon());
            beastBuilder.setName(ServerLanguageMgr.getContent(beastConfig.getName(),language));
            beastBuilder.setDesc(ServerLanguageMgr.getContent(beastConfig.getDesc(),language));
            beastBuilder.setSourPower(beastConfig.getSourPower());
            beastBuilder.setRewards(beastConfig.getRewards());
            configBuild.addBeasts(beastBuilder);
        }

        for(YqHotelEventConfig eventConfig : config.getEventConfigMap().values()){
            YqHotelProto.YqHotelEventConfigTemp.Builder eventBuilder = YqHotelProto.YqHotelEventConfigTemp.newBuilder();
            eventBuilder.setId(eventConfig.getId());
            eventBuilder.setRewards(eventConfig.getRewards());
            eventBuilder.setIcon(eventConfig.getIcon());
            eventBuilder.setDesc(ServerLanguageMgr.getContent(eventConfig.getDesc(),language));
            eventBuilder.setName(ServerLanguageMgr.getContent(eventConfig.getName(),language));

            configBuild.addEvents(eventBuilder);
        }
        for (YqHotelFoodNameConfig names:config.getFoodNameConfigList()){
            YqHotelProto.YqHotelFoodNameConfigTemp.Builder nameBuild = YqHotelProto.YqHotelFoodNameConfigTemp.newBuilder();
            nameBuild.setName(ServerLanguageMgr.getContent(names.getName(),language));
            nameBuild.setId(names.getId());
            configBuild.addNames(nameBuild);
        }

        builder.setConfigData(configBuild);

        return builder;
    }

    public static List<String> getEventConfigRewardList(int eventId){
        return config.getEventConfigMap().get(eventId).getRewardList();
    }

    public static long getCollegeBattleQuickOpenLimit(){
        return config.getYQHOTEL_BATTLE_QUICK_OPEN_LIMIT();
    }

    public static ActivityInfo getActivityInfo(){
        if (config == null) {
            return null;
        }
        return config.getActivityInfo();
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    public static YQHotelConfig getConfig() {
        return config;
    }

    public static boolean activityInTime(){
        if (config == null) {
            return false;
        }

        return ActivityMgr.activityInTime(config.getActivityInfo());
    }

    public static boolean activityInShowTime(){
        if (config == null) {
            return false;
        }

        return ActivityMgr.activityInShowTime(config.getActivityInfo());
    }


    //获取学生武魂类型
    public static int getRandomSoulType(int notThisOne){
        int randomValue = 0;
        int yqhotelSkillNameNum = config.getYQHOTEL_SKILL_NAME_NUM();
        if(notThisOne == 0){
            randomValue = randomHelper.next(1, yqhotelSkillNameNum + 1);
        }else{
            randomValue = randomHelper.next(1, yqhotelSkillNameNum);
            if(randomValue >= notThisOne){
                randomValue++;
            }
        }
        return randomValue;
    }
}
